import os
import tarfile
import re
import cfg
from helpers import substitute, filelist, checkexists


def _has_init(lst):
    for item in lst:
        if item.endswith('__init__.py'):
            return True
    return False

def _contains_file(lst):
    for item in lst:
        if os.path.isfile(item):
            return True
    return False

def _split_files(files):
    files_dict = {}
    packages, data_files = [], []

    for path in files:
        dirname = os.path.dirname(path)
        if not dirname in files_dict:
            files_dict[dirname] = []
        files_dict[dirname].append(path)

    #print files_dict
    #del files_dict['']

    for dir, patches in files_dict.items():
        if _has_init(patches):
            packages.append(dir.replace('/', '.'))
    #    elif _contains_file(patches):
        else:
            data_files.append((dir, patches))

    return packages, data_files

def create(
    info,
    dirname=None,
    skipfiles=None,
    skippathes=None,
):
    """
    1) create `setup.py` file based on `setup.py.template`
    2) create `MANIFEST` for setup.py
    Replaces:
        %NAME%: package name
        %VERSION% - current version
        %PACKAGES% - repr(list of python modules)
        %DATA_FILES% - repr(list of packages)
    """
    dirname = dirname or info.name
    template = cfg.TEMPLATES_DIR + '/setup.py.template'

    checkexists([dirname, template])
    clean()

    skipfiles_default = '.*\.pyc|.*\.pyo|\.svn'
    files = filelist(dirname, skipfiles or skipfiles_default, skippathes)
    files = filter(os.path.isfile, files)

    add_files = ['setup.py']
    open('MANIFEST', 'w').write('\n'.join(add_files + files))
    #open('MANIFEST', 'w').write('\n'.join(files))

    packages, data_files = _split_files(files)
    #del data_files[0]

    replaces = {
        '%PACKAGES%': repr(packages),
        '%SCRIPTS%': repr(getattr(info, 'scripts', [])),
        '%DATA_FILES%': repr(data_files),
    }
    replaces.update(info.get_replaces())
    substitute(template, 'setup.py', replaces)

def clean():
    """
    Delete generated files
    """
    toclean = (
        'MANIFEST',
        'MANIFEST.in',
        'setup.py',
    )
    for file in toclean:
        if os.path.exists(file):
            os.unlink(file)

def package_name_from_targz(filename):
    if not filename.endswith('.tar.gz'):
        raise Exception, '%s: unknown file format' % filename
    return os.path.basename(filename)[:-len('.tar.gz')]

def parse_targz(filename):
    name = package_name_from_targz(filename)

    tar = tarfile.open(filename)
    try:
        setup_py_contents = tar.extractfile('%s/setup.py' % name)

    except KeyError:
        raise Exception, 'No setup.py in arhive'

    setup_re = re.compile('^[^#]*setup\((.+)\)', re.S + re.M)
    m = setup_re.search(setup_py_contents.read())
    if m is None:
        raise Exception, 'Cannot parse setup.py'

    params = {}
    for line in m.group(1).split('\n'):
        line = line.strip()
        if line == '' or line[-1] != ',':
            continue

        line = line[:-1]

        bits = line.split('=', 1)
        if len(bits) != 2:
            continue

        params[bits[0].strip(''' '"''')] = bits[1].strip(''' '"''')

    return params
